home *** CD-ROM | disk | FTP | other *** search
- /*
- * PDEF4.c.
- *
- * Generic daisy/dot matrix text printer driver for the Macintosh.
- * Earle R. Horton August 31, 1987
- * All rights reserved.
- *
- * This module contains the code for validating, creating,
- * and modifying print records.
- */
- /*
- * This module is to be placed into a code resource project using LightspeedC,
- * version 2.01 or greater. The project is to be made into PDEF resource
- * number 4. All of the code up to and including the first illegal instruction
- * is to be stripped off, so that the PDEF will have the standard format for
- * resources of this type. Switch statements cannot be used, since LightspeedC
- * compiles them into separate code which is added to the beginning of the
- * code resource, before our standard header. I do not know at this point
- * which types of flow control constructs are safe, but I have determined by
- * disassembly that the following will produce useable code:
- * if, if/else blocks
- * gotos
- *
- * Instructions, or "How I did it."
- * Create from this module a code resource of type 'pdef' ID 4.
- * Run the program utils.c to make it into PDEF ID 4 and to strip
- * off the standard header.
- */
-
- #include <DialogMgr.h>
- #include <EventMgr.h>
- #include "prglobals.h"
- #define STYLEDIALOG (0xE000)
- #define JOBDIALOG (0xE001)
- #define XTRA 24 /* Six extra longs for our use. */
- #define DLGSIZE ((long)(sizeof(TPrDlg) + XTRA))
- #define TPSIZE ((long)(sizeof(TPrint)))
- /* Items we handle in the job and style dialogs. */
- #define CANCELITEM 2
- #define CPI10BUTTON 4
- #define CPI12BUTTON 5
- #define CPI15BUTTON 6
- #define STRAIGHTUPITEM 7
- #define SIDEWAYSITEM 8
- #define ALLBUTTON 5
- #define RANGEBUTTON 6
- #define FROMNUM 7
- #define TONUM 9
- #define COPIES 11
- #define FANBUTTON 13
- #define SHEETBUTTON 14
-
- pascal void MyPrintDefault(); /* Fill a print record with defaults. */
- pascal Boolean MyPrStlDialog(); /* Conduct printer style dialog. */
- pascal Boolean MyPrJobDialog(); /* Conduct printer job dialog. */
- pascal TPPrDlg MyPrStlInit(); /* Set up the style dialog. */
- pascal TPPrDlg MyPrJobInit(); /* Set up the job dialog. */
- pascal Boolean MyPrDlgMain(); /* Printing dialog supervisor function. */
- pascal Boolean MyPrValidate(); /* Validate/update a print record. */
- pascal void MyPrJobMerge(); /* Copy a job subrecord. */
- pascal Boolean MyFilter(); /* Filter dialog events. */
- pascal void HandleStyleItems(); /* Handle Style Items. */
- pascal void HandleJobItems(); /* Handle Job Items. */
- TPPrDlg TPPrDlgallocate();
- void pushradiobutton();
- int NumToString(),StringToNum();
- Boolean Valid();
- void mkDefault();
- void free();
- main()
- {
- asm{
- dc.w ILLEGAL ;; So I can find it...
- jmp MyPrintDefault
- jmp MyPrStlDialog
- jmp MyPrJobDialog
- jmp MyPrStlInit
- jmp MyPrJobInit
- jmp MyPrDlgMain
- jmp MyPrValidate
- jmp MyPrJobMerge
-
- }
- }
- /*
- * This function fills a print record with defaults. The default values
- * are stored in the Printer resource file, in PREC 0. This is easy. Then
- * we check the fields of the print record for anything obviously illegal.
- * If the default print record contains stuff that is bad, then we correct
- * it and update the copy in the printer resource file. This should never
- * happen, but some wise guy with a copy of ResEdit and more brains than
- * sense may think he knows more than we do.
- */
- pascal void MyPrintDefault(hPrint)
- THPrint hPrint;
- {
- THPrint thedefault;
- thedefault = (THPrint)(GetResource('PREC',0));
- if(thedefault == nil){
- mkDefault(hPrint);
- }
- else{
- LoadResource(thedefault);
- if(MyPrValidate(thedefault)) {
- ChangedResource(thedefault);
- WriteResource(thedefault);
- }
- **hPrint = **thedefault; /* What the hell. */
- }
- }
- pascal Boolean MyPrStlDialog(hPrint) /* Conduct printer style dialog. */
- THPrint hPrint;
- {
- return(MyPrDlgMain(hPrint,MyPrStlInit));
- }
- pascal Boolean MyPrJobDialog(hPrint) /* Conduct printer job dialog. */
- THPrint hPrint;
- {
- return(MyPrDlgMain(hPrint,MyPrJobInit));
- }
- /*
- * The style dialog initializer.
- */
- pascal TPPrDlg MyPrStlInit(hPrint)
- THPrint hPrint;
- {
- TPPrDlg tp;
- tp = TPPrDlgallocate();
- (GetNewDialog(STYLEDIALOG,tp,-1));
- if((*hPrint)->prInfo.iDev == IDEV10)
- pushradiobutton(tp,CPI10BUTTON,CPI10BUTTON,CPI15BUTTON);
- else if((*hPrint)->prInfo.iDev == IDEV12)
- pushradiobutton(tp,CPI12BUTTON,CPI10BUTTON,CPI15BUTTON);
- else if((*hPrint)->prInfo.iDev == IDEV15)
- pushradiobutton(tp,CPI15BUTTON,CPI10BUTTON,CPI15BUTTON);
- pushradiobutton(tp,STRAIGHTUPITEM,STRAIGHTUPITEM,SIDEWAYSITEM);
- tp->pFltrProc = (ProcPtr)MyFilter;
- tp->pItemProc = (ProcPtr)HandleStyleItems;
- tp->hPrintUsr = hPrint;
-
- return(tp);
- }
- /*
- * The job dialog initializer.
- */
- pascal TPPrDlg MyPrJobInit(hPrint)
- THPrint hPrint;
- {
- TPPrDlg tp;
- int thenum;
- Handle theitem;
- Rect thebox;
- Str36 title;
- tp = TPPrDlgallocate();
- (GetNewDialog(JOBDIALOG,tp,-1));
- pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
- if( (*hPrint)->prStl.feed == feedCut)
- pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
- else
- pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
- GetDItem(tp,FROMNUM,&thenum,&theitem,&thebox);
- thenum = (*hPrint)->prJob.iFstPage;
- NumToString((long)thenum,title);
- SetIText(theitem,title);
-
- GetDItem(tp,TONUM,&thenum,&theitem,&thebox);
- thenum = (*hPrint)->prJob.iLstPage;
- NumToString((long)thenum,title);
- SetIText(theitem,title);
-
- GetDItem(tp,COPIES,&thenum,&theitem,&thebox);
- thenum = (*hPrint)->prJob.iCopies;
- NumToString((long)thenum,title);
- SetIText(theitem,title);
-
- tp->pFltrProc = (ProcPtr)MyFilter;
- tp->pItemProc = (ProcPtr)HandleJobItems;
- tp->hPrintUsr = hPrint;
- return(tp);
- }
- pascal Boolean MyPrDlgMain(hPrint,pDlgInit)
- /* Printing dialog supervisor function. */
- /* Reference: Macintosh Technical Note */
- /* 95. Good luck! */
- THPrint hPrint;
- ProcPtr pDlgInit;
- {
- TPPrDlg tp;
- WindowPtr tempport;
- int donetype,itemhit;
- Handle doneitem;
- Rect donebox;
- ProcPtr itemproc;
- asm{
- subq.l #4,a7 ;; Room for function return.
- move.l hPrint,-(a7) ;; Pass handle to print record.
- move.l pDlgInit,a0 ;; Get address of dialog init routine.
- jsr (a0) ;; It's a "Pascal" routine.
- move.l (a7)+,tp ;; Pop return value.
- }
- itemproc = tp->pItemProc;
- tp->fDone = FALSE;
- tp->fDoIt = FALSE;
- GetPort(&tempport);
- SetPort(tp);
- ShowWindow(tp);
- GetDItem(tp,DONEITEM,&donetype,&doneitem,&donebox);
- PenSize(3,3);
- InsetRect(&donebox,-4,-4);
- FrameRoundRect(&donebox,16,16);
- while(!(tp->fDone)){
- ModalDialog(tp->pFltrProc,&itemhit);
- /*
- * Reverse parameters on the call to pItemProc. The application is allowed
- * to trap our pItemProc and insert its own, so we must use the Pascal
- * calling conventions here. Programming novices can use the LightspeedC™
- * CallPascal library if they want. You will have to be careful if you do
- * this to make sure the library is linked AFTER the module containing these
- * functions, or you won't get the PDEF resource header right.
- */
- asm{
- move.l tp,-(a7)
- move.w itemhit,-(a7)
- move.l itemproc,a0
- jsr (a0)
- }
- }
- SetPort(tempport);
- CloseDialog(tp);
- free(tp);
- if(tp->fDoIt) (void)MyPrValidate(hPrint);
- return(tp->fDoIt);
- }
- /*
- * Validate/update a print record. Check all the fields for compatibility with
- * our driver. This is a three stage process. First, we check all fields to
- * see whether they are within the bounds which our driver can handle. If
- * they are, we return FALSE (no change). If not, we obtain a copy of the
- * current default values from the printer resource file. Then we inspect
- * these to see if they are valid. If the default values in the printer
- * resource file are valid, we use them, update the user's print record,
- * and return TRUE (changed). Otherwise, we fall back on default values
- * which we store in the code here. This three stage process provides some
- * protection against the user who attempts to adjust the print record using
- * a resource editor, and screws up.
- */
- pascal Boolean MyPrValidate(hPrint) /* Validate/update a print record. */
- THPrint hPrint;
- {
- THPrint thedefault;
- if(Valid(hPrint)) return FALSE;
- else{
- thedefault = (THPrint)(GetResource('PREC',0));
- LoadResource(thedefault);
- if(thedefault == nil || !Valid(thedefault)) mkDefault(hPrint);
- else{
- **hPrint = **thedefault;
- }
- return TRUE;
- }
- }
- pascal void MyPrJobMerge(hPrintSrc,hPrintDst)
- /*
- * Copy a job subrecord. Update the destination record's printer information,
- * band information, and paper rectangle, based on information in the job
- * subrecord.
- */
- THPrint hPrintSrc,hPrintDst;
- {
- (*hPrintDst)->prInfo.iDev = (*hPrintSrc)->prInfo.iDev;
- (*hPrintDst)->prJob = (*hPrintSrc)->prJob;
- (*hPrintDst)->prXInfo = (*hPrintSrc)->prXInfo;
- (*hPrintDst)->rPaper = (*hPrintSrc)->rPaper;
- (*hPrintDst)->prInfo = (*hPrintSrc)->prInfo;
- (*hPrintDst)->prInfoPT = (*hPrintSrc)->prInfoPT;
- }
- pascal Boolean MyFilter(thedialog,theEvent,itemhit)
- DialogPtr thedialog;
- EventRecord *theEvent;
- int *itemhit;
- {
- if(theEvent->what == keyDown &&
- (theEvent->message & charCodeMask) == 13){
- *itemhit = 1;
- return TRUE;
- }
- return FALSE;
- }
- /*
- * The next routine handles the style dialog. Two possibilities exist.
- * If the cancel button is hit, then we signal quit. The print record
- * is not changed.
- * If the done button is hit, we validate the user's print record.
- * (MyPrDlgMain() calls MyPrValidate() to do this.)
- * We use three radio buttons to determine the number of characters
- * per inch (resolution), and two to determine paper orientation.
- */
- pascal void HandleStyleItems(tp,itemhit)
- TPPrDlg tp;
- int itemhit;
- {
- int thenum;
- Handle theitem;
- Rect thebox;
- if(itemhit >= CPI10BUTTON && itemhit <= CPI15BUTTON)
- pushradiobutton(tp,itemhit,CPI10BUTTON,CPI15BUTTON);
- else if(itemhit >= STRAIGHTUPITEM && itemhit <= SIDEWAYSITEM)
- pushradiobutton(tp,itemhit,STRAIGHTUPITEM,SIDEWAYSITEM);
- else if(itemhit == DONEITEM){
- TPrint Print;
- TPPrint pPrint;
- pPrint = &Print;
- mkDefault(&pPrint);
- (*tp->hPrintUsr)->iPrVersion = Print.iPrVersion;
- (*tp->hPrintUsr)->prInfo = Print.prInfo;
- (*tp->hPrintUsr)->prXInfo = Print.prXInfo;
- (*tp->hPrintUsr)->rPaper = Print.rPaper;
- (*tp->hPrintUsr)->prStl = Print.prStl;
- (*tp->hPrintUsr)->prInfoPT = Print.prInfoPT;
- GetDItem(tp,CPI10BUTTON,&thenum,&theitem,&thebox);
- if(GetCtlValue(theitem) == 1){
- (*tp->hPrintUsr)->prInfo.iDev = IDEV10;
- }
- GetDItem(tp,CPI12BUTTON,&thenum,&theitem,&thebox);
- if(GetCtlValue(theitem) == 1){
- (*tp->hPrintUsr)->prInfo.iDev = IDEV12;
- }
- GetDItem(tp,CPI15BUTTON,&thenum,&theitem,&thebox);
- if(GetCtlValue(theitem) == 1){
- (*tp->hPrintUsr)->prInfo.iDev = IDEV15;
- }
- GetDItem(tp,SIDEWAYSITEM,&thenum,&theitem,&thebox);
- if(GetCtlValue(theitem) == 1){
- int temp;
- flipRect(&(*tp->hPrintUsr)->prInfo.rPage);
- flipRect(&(*tp->hPrintUsr)->rPaper);
- flipRect(&(*tp->hPrintUsr)->prInfoPT.rPage);
- temp = (*tp->hPrintUsr)->prStl.iPageV;
- (*tp->hPrintUsr)->prStl.iPageV =
- (*tp->hPrintUsr)->prStl.iPageH;
- (*tp->hPrintUsr)->prStl.iPageH = temp;
- }
- tp->fDone = TRUE;
- tp->fDoIt = TRUE;
- }
- else if (itemhit == CANCELITEM){
- tp->fDone = TRUE;
- tp->fDoIt = FALSE;
- }
- }
- pascal void HandleJobItems(tp,itemhit)
- TPPrDlg tp;
- int itemhit;
- {
- int thenum;
- long thelong;
- Handle numitem;
- Rect numbox;
- Str36 title;
- if(itemhit == DONEITEM){ /* NO SWITCHES! */
- tp->fDone = TRUE; /* At least until I get a */
- tp->fDoIt = TRUE; /* better compiler. */
- GetDItem(tp,ALLBUTTON,&thenum,&numitem,&numbox);
- if(GetCtlValue(numitem) == 1){
- (*(tp->hPrintUsr))->prJob.iFstPage = iPrPgFst;
- (*(tp->hPrintUsr))->prJob.iLstPage = iPrPgMax;
- }
- else{
- GetDItem(tp,FROMNUM,&thenum,&numitem,&numbox);
- GetIText(numitem,&title[0]);
- StringToNum(&title[0],&thelong);
- (*(tp->hPrintUsr))->prJob.iFstPage = thelong;
- GetDItem(tp,TONUM,&thenum,&numitem,&numbox);
- GetIText(numitem,&title[0]);
- StringToNum(&title[0],&thelong);
- (*(tp->hPrintUsr))->prJob.iLstPage = thelong;
- }
- GetDItem(tp,COPIES,&thenum,&numitem,&numbox);
- GetIText(numitem,&title[0]);
- StringToNum(&title[0],&thelong);
- (*(tp->hPrintUsr))->prJob.iCopies = thelong;
- GetDItem(tp,SHEETBUTTON,&thenum,&numitem,&numbox);
- if(GetCtlValue(numitem) == 1){
- (*(tp->hPrintUsr))->prStl.feed = feedCut;
- }
- else (*(tp->hPrintUsr))->prStl.feed = feedFanfold;
- }
- else if (itemhit == CANCELITEM){
- tp->fDone = TRUE;
- }
- else if (itemhit == SHEETBUTTON){
- pushradiobutton(tp,SHEETBUTTON,FANBUTTON,SHEETBUTTON);
- (*(tp->hPrintUsr))->prStl.feed = feedCut;
- }
- else if (itemhit == FANBUTTON){
- pushradiobutton(tp,FANBUTTON,FANBUTTON,SHEETBUTTON);
- (*(tp->hPrintUsr))->prStl.feed = feedFanfold;
- }
- else if (itemhit == ALLBUTTON){
- pushradiobutton(tp,ALLBUTTON,ALLBUTTON,RANGEBUTTON);
- }
- else if (itemhit == RANGEBUTTON){
- pushradiobutton(tp,RANGEBUTTON,ALLBUTTON,RANGEBUTTON);
- }
- }
- TPPrDlg TPPrDlgallocate()
- {
- TPPrDlg thepointer;
- asm{
- move.l #DLGSIZE,d0
- NewPtr
- move.l a0,thepointer
- }
- if(thepointer == nil){ /* We're in deep shit now! */
- asm{
- move.w #25,d0
- SysError ;; SysError
- }
- }
- return(thepointer);
- }
- void pushradiobutton(thedialog,itemhit,first,last) /* push a radio Button */
- DialogPtr thedialog; /* set itemhit, unset */
- int itemhit,first,last; /* all others in range */
- {
- int itemtype,i;
- Handle itemhandle; /* Does check boxes, too. */
- Rect itemrect;
- if(first ==0) return;
- for(i=first-1;last-i++;){
- GetDItem(thedialog,i,&itemtype,&itemhandle,&itemrect);
- if(i == itemhit) SetCtlValue(itemhandle,1);
- else SetCtlValue(itemhandle,0);
- }
- }
- NumToString(thenum,thestring)
- long thenum;
- char *thestring;
- {
- asm{
- move.l thestring,a0
- move.l thenum,d0
- move.w #0,-(a7)
- Pack7
- }
- }
- StringToNum(thestring,thenum)
- char *thestring;
- long *thenum;
- {
- asm{
- move.l thestring,a0
- move.w #1,-(a7)
- Pack7
- move.l thenum,a0
- move.l d0,(a0)
- }
- }
- /*
- * This function answers the question: Can we possibly use this print
- * record?
- */
- Boolean Valid(hPrint)
- THPrint hPrint;
- {
- if (((*hPrint)->iPrVersion != VERSION)
- || ((*hPrint)->prInfo.iDev != IDEV12 &&
- (*hPrint)->prInfo.iDev != IDEV10 &&
- (*hPrint)->prInfo.iDev != IDEV15)
- || ((*hPrint)->prInfo.iVRes != VREZZ)
- || ((*hPrint)->prInfo.iHRes != HREZZ12)
- || ((*hPrint)->prInfo.rPage.top !=0 ||
- (*hPrint)->prInfo.rPage.left !=0)
- || ((*hPrint)->rPaper.right -
- (*hPrint)->rPaper.left > 11 * HREZZ12)
- || ((*hPrint)->rPaper.bottom -
- (*hPrint)->rPaper.top > 11 * VREZZ)
- || ((*hPrint)->prStl.feed != feedCut &&
- (*hPrint)->prStl.feed != feedFanfold)
- || ((*hPrint)->prJob.bJDocLoop != bDraftLoop))
-
- return FALSE;
-
- else return TRUE;
- }
- void free(ptr)
- char *ptr;
- {
- asm{
- move.l ptr,a0
- DisposPtr
- }
- }
- flipRect(rect)
- Rect *rect;
- {
- asm{
- move.l rect,a0
- move.l (a0),d0
- swap d0 ;; swap top, left
- move.l d0,(a0)+
- move.l (a0),d0
- swap d0 ;; swap bottom, right
- move.l d0,(a0)
- }
- }
-
- #include "mkDefault.c"
-
-